﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using System.Threading;

namespace SPExplorer
{
  public partial class SPExplorerForm : Form
  {
    SPExplorerDocument document;

    public static string imagePath12 = @"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\IMAGES\";
    public static string imagePath14 = @"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IMAGES\";

    Dictionary<string, string> iconMap = new Dictionary<string, string>() { 
    // node      icon
    { "default", "square.gif" }, 
    { "Farm", "cnf16.gif" },
    { "WebServices", "cdf16.gif" },
    { "WebService", "icasmx.gif" },
    { "WebApplications", "tbnail.gif" },
    { "WebApplication", "icasax.gif" },
    { "Sites", "icstp.gif" },
    { "Site", "stsicon.gif" },
    { "Webs", "cdx16.gif" }, 
    { "Web", "ichtt.gif" }, 
    { "Files", "existinglocations.gif"}, 
    { "File", "noextension16.gif" }, 
    { "UserLists", "iii16.gif" }, 
    { "User", "ppl_16.gif" }, 
    { "List", "nws16.gif" },
    { "MetaData", "icstorage.gif" },
    { "Fields", "checkitems.gif" }, 
    { "Field", "vcf16.gif" }, 
    { "FieldRefs", "totalrow.gif" }, 
    { "FieldRef", "reorder.gif" }, 
    { "Form", "WebApplicationConnections.gif" }, 
    { "Forms", "model_sp16.gif" }, 
    { "Folder", "folder.gif" },
    { "DisplayPattern", "maf16.gif" },
    { "Rows", "mav16.gif" },
    { "Row", "mat16.gif" },
    { "Column", "chngcol.gif" },
    { "ContentTypes", "urn-content-classes-categoryfolder16.gif" },
    { "ContentType", "urn-content-classes-smartfolder16.gif" },
    { "Data", "icodcd.gif" },
    { "Security", "prf16.gif" },
    { "WebPart", "webpart.gif" },
    { "HTML", "icdwp.gif" },
    { "LookupColumn", "icprop.gif" },
    { "URL", "exptitem.gif" },
    { "ScriptQuote", "wsh16.gif" },
    { "CurrentRights", "icaccdc.gif" },
    { "Workflow", "workflows.gif" },
    { "Collection", "mag16.gif" },
    { "Error", "error16by16.gif" } };


    public SPExplorerForm()
    {
      InitializeComponent();
      LoadTreeViewIcons();
      document = new SPExplorerDocument();
      RefreshTreeView();
    }

    private void LoadTreeViewIcons()
    {
      string imageDirectory = imagePath12;
      if (!Directory.Exists(imageDirectory)) imageDirectory = imagePath14;
      if (Directory.Exists(imageDirectory))
      {
        ImageList images = new ImageList();
        foreach (KeyValuePair<string, string> item in iconMap)
        {
          string filepath = imageDirectory + item.Value;
          if (File.Exists(filepath))
          {
            Image icon = Image.FromFile(filepath);
            images.Images.Add(item.Key, icon);
          }
        }
        treeView.ImageList = images;
      }
    }

    private void Render(XmlNode xmlNode, TreeNodeCollection treeNodes)
    {
      if (xmlNode == null) return;
      if (xmlNode.NodeType != XmlNodeType.Element) return;
      TreeNode childTreeNode = new TreeNode(NodeTitle(xmlNode, showElementNamesToolStripMenuItem.Checked, false));
      if (childTreeNode.Text.Length == 0)
      { // show greyed node name
        childTreeNode.Text = xmlNode.Name;
        childTreeNode.ForeColor = Color.Gray;
      }
      childTreeNode.Tag = xmlNode;
      childTreeNode.ImageKey = xmlNode.Name;
      childTreeNode.SelectedImageKey = xmlNode.Name;
      childTreeNode.ToolTipText = NodeTitle(xmlNode, true, true);
      treeNodes.Add(childTreeNode);
      foreach (XmlNode childNode in xmlNode.ChildNodes) Render(childNode, childTreeNode.Nodes);
    }

    private static string NodeTitle(XmlNode xmlNode, bool showNodeName, bool showDescription)
    {
      string nodeName = "";
      if (showNodeName) nodeName += xmlNode.Name;
      XmlNode title = xmlNode.Attributes["Title"];
      XmlNode name = xmlNode.Attributes["Name"];
      if (title != null && title.Value.Length > 0)
        nodeName += (showNodeName ? " (" : "") + title.Value + (showNodeName ? ")" : "");
      else if (name != null && name.Value.Length > 0)
        nodeName += (showNodeName ? " (" : "") + name.Value + (showNodeName ? ")" : "");
      if (showDescription)
      {
        XmlNode url = xmlNode.Attributes["Url"];
        if (url != null && url.Value.Length > 0)
          nodeName += " " + url.Value + "  ";
        XmlNode description = xmlNode.Attributes["Description"];
        if (description != null && description.Value.Length > 0)
          nodeName += " " + description.Value;
      }
      return nodeName;
    }

    private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
    {
      Cursor.Current = Cursors.WaitCursor;
      if (treeView.SelectedNode == null)
      {
        textView.Text = "";
        return;
      }
      treeView.SelectedNode.EnsureVisible();
      toolStripStatusLabel.Text = treeView.SelectedNode.ToolTipText;
      // render XML as text
      XmlNode node = (XmlNode)treeView.SelectedNode.Tag;
      StringBuilder sb = new StringBuilder();
      XmlWriter xw = XmlWriter.Create(sb, SPExplorerDocument.WriteSettings());
      node.WriteTo(xw);
      xw.Close();
      textView.Text = sb.ToString();
      Cursor.Current = Cursors.Default;
    }

    private void expandAllToolStripMenuItem_Click(object sender, EventArgs e)
    {
      Cursor.Current = Cursors.WaitCursor;
      treeView.ExpandAll();
      if (treeView.SelectedNode == null && treeView.Nodes.Count > 0)
        treeView.SelectedNode = treeView.Nodes[0];
      if (treeView.SelectedNode != null) treeView.SelectedNode.EnsureVisible();
      Cursor.Current = Cursors.Default;
    }

    private void collapseAllToolStripMenuItem_Click(object sender, EventArgs e)
    {
      if (treeView.Nodes.Count > 0) treeView.SelectedNode = treeView.Nodes[0];
      else textView.Text = "";
      treeView.CollapseAll();
      if (treeView.SelectedNode != null) treeView.SelectedNode.EnsureVisible();
    }

    private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
    {
      AboutBox dlg = new AboutBox();
      dlg.ShowDialog(this);
    }

    private void RefreshTreeView()
    {
      Cursor.Current = Cursors.WaitCursor;
      treeView.Nodes.Clear();
      Render(document.DocumentElement, treeView.Nodes);
      treeView.ShowNodeToolTips = !showElementNamesToolStripMenuItem.Checked;
      treeView.ExpandAll();
      treeView.Refresh();
      if (treeView.Nodes.Count > 0) treeView.SelectedNode = treeView.Nodes[0];
      else textView.Text = "";
      if (treeView.SelectedNode != null) treeView.SelectedNode.EnsureVisible();
      Cursor.Current = Cursors.Default;
    }

    private void showElementNamesToolStripMenuItem_Click(object sender, EventArgs e)
    {
      RefreshTreeView();
    }

    private void readLocalFarmToolStripMenuItem_Click(object sender, EventArgs e)
    {
      try
      {
        Cursor.Current = Cursors.WaitCursor;
        document.ReadFromLocalFarm();
        RefreshTreeView();
      }
      catch (ApplicationException)
      {
        MessageBox.Show("Could not open local farm", "Error");
      }
      catch (System.Data.SqlClient.SqlException ex)
      {
        if (ex.Message.Contains("login failed"))
          MessageBox.Show("Could not log in to local farm - have you tried running as administrator?", "SQL Server Error");
        else
          MessageBox.Show("Could not open local farm", "SQL Server Error");
      }
      finally
      {
        Cursor.Current = Cursors.Default;
      }
    }

    private void readXMLToolStripMenuItem_Click(object sender, EventArgs e)
    {
      OpenFileDialog dlg = new OpenFileDialog();
      dlg.InitialDirectory = Directory.GetCurrentDirectory();
      dlg.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*";
      dlg.RestoreDirectory = true;
      dlg.SupportMultiDottedExtensions = true;
      if (dlg.ShowDialog(this) == DialogResult.OK)
      {
        document.RemoveAll();
        document.ReadFromFile(dlg.FileName);
        RefreshTreeView();
      }
    }

    private void saveXMLToolStripMenuItem_Click(object sender, EventArgs e)
    {
      SaveFileDialog dlg = new SaveFileDialog();
      dlg.InitialDirectory = Directory.GetCurrentDirectory();
      dlg.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*";
      dlg.RestoreDirectory = true;
      dlg.SupportMultiDottedExtensions = true;
      if (dlg.ShowDialog(this) == DialogResult.OK)
      {
        document.SaveToFile(dlg.FileName);
      }
    }

    private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    {
      Application.Exit();
    }

    private void statusBarToolStripMenuItem_Click(object sender, EventArgs e)
    {
      statusStrip.Visible = statusBarToolStripMenuItem.Checked;
      toolStripStatusLabel.Visible = statusBarToolStripMenuItem.Checked;
    }

    private void contentToolStripMenuItem_Click(object sender, EventArgs e)
    {
      document.IncludeContent = contentToolStripMenuItem.Checked;
    }
  }
}
